<template>
  <el-dialog :close-on-click-modal='false' v-drag :title="$t(title)" :v-if="dialogVisible" :visible.sync="dialogVisible" :width="lang === 'zh'?'680px':'740px'" top='5vh' @close='close'>
    <div class="dialogContentBox DnatContent">
      <el-form ref="form" :model="record" :label-width="lang === 'zh'?'150px':'160px'" :rules="rules" label-position="left" style="margin:0 20px;">
        <el-form-item :label="$t('策略名称')" prop="policyname">
          <span slot="label" class="dnatRequired">{{$t('策略名称')}}</span>
          <el-input v-emoji v-model="record.policyname" ref="policyname" style="width:217px;" size='small'></el-input>
        </el-form-item>
        <el-divider content-position="left">{{$t('转换前匹配')}}</el-divider>
        <el-form-item :label="$t('IP类型')" prop="iptype">
          <el-radio v-model="record.iptype" label="ipv4" class="ipv4" :disabled='record.id ? true : false'>IPv4</el-radio>
          <el-radio v-model="record.iptype" label="ipv6" class="ipv6" :disabled='record.id ? true : false'>IPv6</el-radio>
        </el-form-item>
        <el-form-item :label="$t('源IP')" prop="sip">
          <el-select v-model="record.sip" ref="sip" :placeholder="$t('请选择')" size='small' filterable clearable>
            <el-option v-for="item in filMac(srcList)" :key="item.name" :label="item.nameShow" :value="item.name">
            </el-option>
          </el-select>
          <addr-dialog @commandList='commandList' :nameType='"sip"'></addr-dialog>
          <el-tooltip class="item" effect="light" :content="$t('如不选择源IP可能导致防火墙管理口连接不上！')" placement="top">
            <i class="el-icon-warning-outline" style="color:#FF0000;font-size:16px;"></i>
          </el-tooltip>
        </el-form-item>
        <!-- <el-form-item :label="$t('协议')" prop="proto">
          <el-select v-model="record.proto" :placeholder="$t('请选择')" size='small' @change="protoChange" filterable clearable>
            <el-option v-for="item in protoList" :key="item.value" :label="item.label" :value="item.value">
            </el-option>
          </el-select>
        </el-form-item>
        <el-form-item :label="$t('源端口号')" prop="sport">
          <el-input v-emoji v-model="record.sport" style="width:217px;" :disabled='(record.proto?false:true) || record.proto === "nothing"' size='small'></el-input>
        </el-form-item> -->
        <el-form-item :label="$t('目的IP')" prop="dip">
          <el-select v-model="record.dip" ref="dip" :placeholder="$t('请选择')" size='small' filterable clearable>
            <el-option v-for="item in filMac(dstList)" :key="item.name" :label="item.nameShow" :value="item.name">
            </el-option>
          </el-select>
          <addr-dialog @commandList='commandList' :nameType='"dip"'></addr-dialog>
          <el-tooltip class="item" effect="light" :content="$t('如不选择目的IP可能导致防火墙管理口连接不上！')" placement="top">
            <i class="el-icon-warning-outline" style="color:#FF0000;font-size:16px;"></i>
          </el-tooltip>
        </el-form-item>
        <el-form-item :label="$t('服务')" prop="service">
          <el-select v-model="record.service" ref="service" :placeholder="$t('请选择')" size='small' filterable clearable @change="handleService">
            <el-option v-for="item in iservicepsList" :key="item.id" :label="item.name" :value="item.name">
            </el-option>
          </el-select>
          <ServerDialog @serviceList='serviceList'></ServerDialog>
        </el-form-item>
        <el-divider content-position="left">{{$t('转换后配置')}}</el-divider>
        <el-form-item :label="$t('地址池')" prop="addrpool">
          <span slot="label" class="dnatRequired">{{$t('地址池')}}</span>
          <el-input v-emoji v-model="record.addrpool" ref="addrpool" style="width:217px;" size='small'></el-input>
          <el-tooltip class="item" effect="light" placement="right">
            <div slot="content">
              {{$t('转换到地址池中的目的地址是随机的')}}<br />
              {{$t('请确保地址池内每个服务器IP网络是连通的，')}}<br />
              {{$t('否则转换后的数据无法从防火墙设备发出')}}<br />
            </div>
            <i class="el-icon-warning-outline" style="color:#666;font-size:16px;"></i>
          </el-tooltip>
        </el-form-item>
        <el-form-item :label="$t('端口转换开启')" prop="portState" class="portState">
          <span slot="label">{{$t('端口转换开启')}}
            <el-switch :width="47" :disabled="record.service==='ICMPV6' || record.service==='ICMP'" v-model="record.portState" @change="portStateChange" class="portState switch" active-color="#009966" inactive-color="#CCCCCC" active-value="on" inactive-value="off" :active-text="$t('是')" :inactive-text="$t('否')"></el-switch>
          </span>
          <el-input v-emoji v-model="record.port" ref="port" :disabled="record.portState==='off'? true: ['ICMPV6','ICMP'].includes(record.service)" style="width:217px;" size='small'></el-input>
        </el-form-item>
        <el-divider content-position="left">{{$t('策略配置')}}</el-divider>
        <el-form-item :label="$t('策略使能')" prop="enable" class="enable">
          <el-switch :width="46" v-model="record.enable" active-color="#009966" class="enable switch" inactive-color="#CCCCCC" active-value="yes" inactive-value="no" :active-text="$t('开')" :inactive-text="$t('关')"></el-switch>
        </el-form-item>
        <el-form-item :label="$t('日志使能')" prop="log" class="enable">
          <el-switch :width="46" v-model="record.log" active-color="#009966" class="recordLog switch" inactive-color="#CCCCCC" active-value="on" inactive-value="off" :active-text="$t('开')" :inactive-text="$t('关')"></el-switch>
        </el-form-item>
      </el-form>
    </div>
    <span slot="footer" class="dialog-footer">
      <el-button type="primary" @click="submit" class="addSubmit">{{$t('确 定')}}</el-button>
      <el-button @click="close" class="addClose">{{$t('取 消')}}</el-button>
    </span>
  </el-dialog>
</template>
<script>
import { addDnat, editDnat } from '@/api/network/address/dnat'
import { getAddrGroupArray } from '@/api/list/addr-group'
import { getAddrArray } from '@/api/list/addr'
import { getServiceArray, getServiceReArray } from '@/api/list/server'
import addrDialog from './AddrDialog'
import ServerDialog from './ServerDialog'
import { inputClass, selectClass } from '@/utils/input-class.js'
export default {
  name: 'DnatDialog',
  components: {
    addrDialog,
    ServerDialog
  },
  data () {
    var validateName = (rule, value, callback) => {
      if (!String(value).trim()) {
        callback(new Error(this.$t('不能为空')))
      } else {
        callback()
      }
    }
    var validateService = (rule, value, callback) => {
      if (this.record.port && String(value).trim() === '') {
        callback(new Error(this.$t('不能为空')))
      } else {
        callback()
      }
    }
    var validateAddrpool = (rule, value, callback) => {
      if (value.indexOf('-') >= 0) {
        var ipList = value.split('-')
        if (ipList.length < 3) {
          callback(this.ipTest(ipList[0]) || this.ipTest(ipList[1]))
        } else {
          callback(new Error(this.$t('请输入正确的格式')))
        }
      } else {
        callback(this.ipTest(value))
      }
    }
    var validateSport = (rule, value, callback) => {
      if (value === '') {
        callback()
      } else if (isNaN(Number(value))) {
        callback(new Error(this.$t('请输入数字')))
      } else if (Number(value) < 1 || Number(value) > 65535) {
        callback(new Error(this.$t('端口号必须在1-65535之间')))
      } else {
        callback()
      }
    }
    var validatePort = (rule, value, callback) => {
      if (this.record.portState === 'on') {
        if (String(value).trim() === '') {
          callback(new Error(this.$t('不能为空')))
        } else if (isNaN(Number(value))) {
          callback(new Error(this.$t('请输入数字')))
        } else if (Number(value) < 1 || Number(value) > 65535) {
          callback(new Error(this.$t('端口号必须在1-65535之间')))
        } else {
          callback()
        }
      } else {
        callback()
      }
    }
    return {
      dialogVisible: false,
      record: {
        id: null,
        policyname: '',
        iptype: 'ipv4',
        addrpool: '',
        portState: 'off',
        port: '',
        sip: '',
        // proto: '',
        // sport: '',
        dip: '',
        service: '',
        enable: 'yes',
        log: 'on'
      },
      recordCopy: {
        id: null,
        policyname: '',
        iptype: 'ipv4',
        addrpool: '',
        portState: 'off',
        port: '',
        sip: '',
        // proto: '',
        // sport: '',
        dip: '',
        service: '',
        enable: 'yes',
        log: 'on'
      },
      title: '',
      srcList: [],
      dstList: [],
      iservicepsList: [],
      // protoList: ['tcp', 'udp', 'dccp', 'sctp', 'nothing'],
      protoList: [
        { value: 'nothing', label: this.$t('未配置') },
        { value: 'tcp', label: 'tcp' },
        { value: 'udp', label: 'udp' },
        { value: 'dccp', label: 'dccp' },
        { value: 'sctp', label: 'sctp' }
      ],
      lang: this.$i18n.locale,
      rules: {
        policyname: [{ required: false, validator: validateName, trigger: 'blur' }],
        service: [{ required: false, validator: validateService, trigger: 'change' }],
        addrpool: [{ required: false, validator: validateAddrpool, trigger: 'blur' }],
        sport: [{ required: false, validator: validateSport, trigger: 'blur' }],
        port: [{ required: false, validator: validatePort, trigger: 'blur' }]
      }
    }
  },
  methods: {
    handleService(value) {  
      if(value === 'ICMPV6' || value === 'ICMP') {
        this.record.portState = 'off'
        this.record.port = ''
      }
    },
    filMac(list=[]) {
      return list.filter(item => item.ip_type !== 7)
    },
    init (data) {
      this.dialogVisible = true
      this.title = data ? this.$t('编辑') : this.$t('添加')
      this.$nextTick(() => {
        const data = ['policyname', 'addrpool', 'port']
        const selectData = ['sip', 'dip', 'service']
        inputClass(this.$refs, data)
        selectClass(this.$refs, selectData)
      })
      if (data) {
        this.record = Object.assign(this.record, data)
        this.record.id = data.index
        this.record.portState = data.port ? 'on' : 'off'
        this.record.enable = data.PolicyEnableOrNot
        this.record.log = data.LogOpenOrNot
      }
      this.commandList()
      this.serviceList()
    },
    submit () {
      if (!this.record.id) {
        this.$refs.form.validate((valid) => {
          if (valid) {
            addDnat(this.record).then(res => {
              if (res.status === 0) {
                this.$message({
                  message: this.$t('添加成功'),
                  type: 'success'
                })
                this.close()
                this.$parent.listData()
              }
            })
          }
        })
      } else {
        this.$refs.form.validate((valid) => {
          if (valid) {
            editDnat(this.record).then(res => {
              if (res.status === 0) {
                this.$message({
                  message: this.$t('编辑成功'),
                  type: 'success'
                })
                this.close()
                this.$parent.listData()
              }
            })
          }
        })
      }
    },
    close () {
      this.dialogVisible = false
      this.record = Object.assign({}, this.recordCopy)
      this.srcList = []
      this.dstList = []
      this.iservicepsList = []
      this.$refs.form.resetFields()
    },
    commandList (data, nameType, name) {
      this.srcList = []
      this.dstList = []
      getAddrArray().then(response => {
        if (response.status === 0) {
          getAddrGroupArray().then(res => {
            if (res.status === 0) {
              // this.srcList = response.info.concat(res.info)
              // this.dstList = response.info.concat(res.info)
              for (let item of response.info) {
                item.nameShow = this.$t('地址-') + item.name
                this.srcList.push(item)
                this.dstList.push(item)
              }
              for (let item of res.info) {
                item.nameShow = this.$t('地址组-') + item.name
                this.srcList.push(item)
                this.dstList.push(item)
              }
            }
          })
        }
      })
      if (data && nameType === 'sip') {
        this.record.sip = name
      } else if (data && nameType === 'dip') {
        this.record.dip = name
      }
    },
    serviceList (data) {
      this.iservicepsList = []
      getServiceArray().then(response => {
        if (response.status === 0) {
          getServiceReArray().then(res => {
            if (res.status === 0) {
              this.iservicepsList = response.info.concat(res.info)
            }
          })
        }
      })
      if (data) {
        this.record.service = data.name
      }
    },
    ipTest (data) {
      let ipv4 = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
      let ipv6 = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/
      if (data === '') {
        return new Error(this.$t('不能为空'))
      } else if (this.record.iptype === 'ipv4' && !ipv4.test(data)) {
        return new Error(this.$t('请输入正确的ip地址'))
      } else if (this.record.iptype === 'ipv6' && !ipv6.test(data)) {
        return new Error(this.$t('请输入正确的ip地址'))
      }
    },
    portStateChange (data) {
      if (data === 'off') {
        this.record.port = ''
      }
    },
    protoChange (val) {
      if (!val) {
        this.record.sport = ''
        this.$refs.form.clearValidate('sport')
      }
    }
  }
}
</script>
<style lang="less" scoped>
.dialogContentBox {
  max-height: calc(90vh - 184px);
  overflow-y: auto;
}

.dnatRequired:after {
  content: "*";
  color: #ff4949;
  margin-left: 4px;
}
</style>
<style lang="scss">
.DnatContent {
  .el-divider__text {
    font-size: 20px;
    font-weight: 300;
  }
}
</style>
